// 游戏常量
const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 30;
const COLORS = [
    null,        // 0: 空
    '#4285F4',   // 1: I
    '#FBBC05',   // 2: O
    '#EA4335',   // 3: T
    '#34A853',   // 4: S
    '#46BDC6',   // 5: Z
    '#764ABC',   // 6: L
    '#FF6550'    // 7: J
];

// 方块形状 (0:空, 1:有)
const SHAPES = [
    [], // 空
    [ // I
        [0,0,0,0],
        [1,1,1,1],
        [0,0,0,0],
        [0,0,0,0]
    ],
    [ // O
        [2,2],
        [2,2]
    ],
    [ // T
        [0,3,0],
        [3,3,3],
        [0,0,0]
    ],
    [ // S
        [0,4,4],
        [4,4,0],
        [0,0,0]
    ],
    [ // Z
        [5,5,0],
        [0,5,5],
        [0,0,0]
    ],
    [ // L
        [0,0,6],
        [6,6,6],
        [0,0,0]
    ],
    [ // J
        [7,0,0],
        [7,7,7],
        [0,0,0]
    ]
];

// 游戏变量
let canvas, ctx;
let nextCanvas, nextCtx;
let board = []; // 游戏板
let currentPiece = null; // 当前方块
let nextPiece = null; // 下一个方块
let score = 0;
let lines = 0;
let level = 1;
let highScore = localStorage.getItem('tetrisHighScore') || 0;
let dropInterval = 1000; // 下落间隔(毫秒)
let dropCounter = 0; // 下落计数器
let lastTime = 0; // 上次时间
let gameLoopId = null;
let isPaused = false;
let isGameOver = false;
let soundEnabled = true;

// DOM 元素
const startScreen = document.getElementById('startScreen');
const pauseScreen = document.getElementById('pauseScreen');
const gameOverScreen = document.getElementById('gameOverScreen');
const startBtn = document.getElementById('startBtn');
const pauseBtn = document.getElementById('pauseBtn');
const resumeBtn = document.getElementById('resumeBtn');
const restartBtn = document.getElementById('restartBtn');
const soundBtn = document.getElementById('soundBtn');
const soundIcon = document.getElementById('soundIcon');
const scoreDisplay = document.getElementById('score');
const linesDisplay = document.getElementById('lines');
const levelDisplay = document.getElementById('level');
const highScoreDisplay = document.getElementById('highScoreDisplay');
const finalScore = document.getElementById('finalScore');
const gameOverHighScore = document.getElementById('gameOverHighScore');
const leftBtn = document.getElementById('leftBtn');
const rightBtn = document.getElementById('rightBtn');
const rotateBtn = document.getElementById('rotateBtn');
const dropBtn = document.getElementById('dropBtn');

// 初始化游戏
function initGame() {
    // 获取主游戏画布
    canvas = document.getElementById('gameCanvas');
    ctx = canvas.getContext('2d');
    
    // 获取下一个方块画布
    nextCanvas = document.getElementById('nextPiece');
    nextCtx = nextCanvas.getContext('2d');
    
    // 设置画布尺寸
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    
    // 初始化游戏板
    resetBoard();
    
    // 生成初始方块
    currentPiece = getRandomPiece();
    nextPiece = getRandomPiece();
    
    // 更新高分显示
    highScoreDisplay.textContent = highScore;
    
    // 绑定事件监听
    bindEvents();
    
    // 绘制初始状态
    draw();
    drawNextPiece();
}

// 调整画布尺寸
function resizeCanvas() {
    // 主游戏画布
    const container = canvas.parentElement;
    const containerWidth = container.clientWidth;
    const calculatedHeight = ROWS * BLOCK_SIZE;
    
    canvas.width = COLS * BLOCK_SIZE;
    canvas.height = calculatedHeight;
    
    // 下一个方块画布
    nextCanvas.width = 4 * BLOCK_SIZE;
    nextCanvas.height = 4 * BLOCK_SIZE;
    
    // 重新绘制
    if (board.length > 0) {
        draw();
        drawNextPiece();
    }
}

// 初始化游戏板
function resetBoard() {
    board = Array(ROWS).fill().map(() => Array(COLS).fill(0));
    score = 0;
    lines = 0;
    level = 1;
    dropInterval = 1000;
    
    // 更新显示
    updateDisplays();
}

// 获取随机方块
function getRandomPiece() {
    const type = Math.floor(Math.random() * 7) + 1;
    const piece = {
        type,
        shape: SHAPES[type],
        x: Math.floor(COLS / 2) - Math.floor(SHAPES[type][0].length / 2),
        y: 0
    };
    
    return piece;
}

// 绑定事件监听
function bindEvents() {
    // 键盘控制
    window.addEventListener('keydown', handleKeyPress);
    
    // 按钮控制
    startBtn.addEventListener('click', startGame);
    pauseBtn.addEventListener('click', togglePause);
    resumeBtn.addEventListener('click', togglePause);
    restartBtn.addEventListener('click', restartGame);
    soundBtn.addEventListener('click', toggleSound);
    
    // 移动设备控制
    leftBtn.addEventListener('click', () => movePiece(-1, 0));
    rightBtn.addEventListener('click', () => movePiece(1, 0));
    rotateBtn.addEventListener('click', rotatePiece);
    dropBtn.addEventListener('click', hardDrop);
}

// 处理键盘输入
function handleKeyPress(e) {
    if (isPaused || isGameOver) {
        if (e.key === 'p' || e.key === 'P') {
            togglePause();
        }
        return;
    }
    
    switch(e.key) {
        case 'ArrowLeft':
            movePiece(-1, 0);
            break;
        case 'ArrowRight':
            movePiece(1, 0);
            break;
        case 'ArrowDown':
            movePiece(0, 1);
            score += 1; // 下移得1分
            updateDisplays();
            break;
        case 'ArrowUp':
            rotatePiece();
            break;
        case ' ':
            hardDrop();
            break;
        case 'p':
        case 'P':
            togglePause();
            break;
    }
}

// 移动方块
function movePiece(dx, dy) {
    if (isValidMove(currentPiece.x + dx, currentPiece.y + dy, currentPiece.shape)) {
        currentPiece.x += dx;
        currentPiece.y += dy;
        draw();
        return true;
    }
    return false;
}

// 旋转方块
function rotatePiece() {
    // 复制当前形状
    const rotatedShape = [];
    for (let i = 0; i < currentPiece.shape[0].length; i++) {
        rotatedShape[i] = [];
        for (let j = currentPiece.shape.length - 1; j >= 0; j--) {
            rotatedShape[i][j] = currentPiece.shape[j][i];
        }
    }
    
    // 检查旋转后是否有效
    if (isValidMove(currentPiece.x, currentPiece.y, rotatedShape)) {
        currentPiece.shape = rotatedShape;
        draw();
    }
}

// 硬下落（直接到底）
function hardDrop() {
    while (movePiece(0, 1));
    lockPiece();
    if (soundEnabled) playLockSound();
}

// 检查移动是否有效
function isValidMove(x, y, shape) {
    for (let row = 0; row < shape.length; row++) {
        for (let col = 0; col < shape[row].length; col++) {
            if (shape[row][col] !== 0) {
                const newX = x + col;
                const newY = y + row;
                
                // 检查是否超出边界或与已有方块碰撞
                if (
                    newX < 0 || 
                    newX >= COLS || 
                    newY >= ROWS || 
                    (newY >= 0 && board[newY][newX] !== 0)
                ) {
                    return false;
                }
            }
        }
    }
    return true;
}

// 锁定方块到游戏板
function lockPiece() {
    for (let row = 0; row < currentPiece.shape.length; row++) {
        for (let col = 0; col < currentPiece.shape[row].length; col++) {
            if (currentPiece.shape[row][col] !== 0) {
                const x = currentPiece.x + col;
                const y = currentPiece.y + row;
                
                // 如果方块顶部超出屏幕，游戏结束
                if (y < 0) {
                    isGameOver = true;
                    cancelAnimationFrame(gameLoopId);
                    gameOver();
                    return;
                }
                
                // 将方块添加到游戏板
                board[y][x] = currentPiece.type;
            }
        }
    }
    
    // 检查是否有可消除的行
    checkLines();
    
    // 生成新的方块
    currentPiece = nextPiece;
    nextPiece = getRandomPiece();
    drawNextPiece();
    
    // 如果新方块无法放置，游戏结束
    if (!isValidMove(currentPiece.x, currentPiece.y, currentPiece.shape)) {
        isGameOver = true;
        cancelAnimationFrame(gameLoopId);
        gameOver();
    }
}

// 检查并消除完整的行
function checkLines() {
    let linesCleared = 0;
    
    for (let row = ROWS - 1; row >= 0; row--) {
        if (board[row].every(cell => cell !== 0)) {
            // 移除该行
            board.splice(row, 1);
            
            // 在顶部添加一个新的空行
            board.unshift(Array(COLS).fill(0));
            
            // 行计数器加1
            linesCleared++;
            
            // 由于删除了一行，需要重新检查当前行
            row++;
        }
    }
    
    if (linesCleared > 0) {
        // 播放消除行的音效
        if (soundEnabled) playLineClearSound(linesCleared);
        
        // 计算得分 (1行=100, 2行=300, 3行=500, 4行=800)
        const lineScores = [0, 100, 300, 500, 800];
        score += lineScores[linesCleared] * level;
        
        // 更新行数和等级
        lines += linesCleared;
        level = Math.floor(lines / 10) + 1;
        
        // 根据等级调整下落速度
        dropInterval = Math.max(100, 1000 - (level - 1) * 100);
        
        // 更新显示
        updateDisplays();
        
        // 绘制消除动画
        drawLinesClearedAnimation(linesCleared);
    }
}

// 绘制消除行的动画
function drawLinesClearedAnimation(linesCleared) {
    const originalFillStyle = ctx.fillStyle;
    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
    
    // 闪烁动画
    let flashCount = 3;
    const flashInterval = setInterval(() => {
        draw();
        
        if (flashCount % 2 === 0) {
            ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
            
            // 找到被清除的行并高亮显示
            for (let row = 0; row < ROWS; row++) {
                if (board[row].every(cell => cell === 0)) {
                    ctx.fillRect(0, row * BLOCK_SIZE, canvas.width, BLOCK_SIZE);
                }
            }
        }
        
        flashCount--;
        
        if (flashCount < 0) {
            clearInterval(flashInterval);
            ctx.fillStyle = originalFillStyle;
        }
    }, 100);
}

// 开始游戏
function startGame() {
    startScreen.classList.add('hidden');
    isPaused = false;
    isGameOver = false;
    resetBoard();
    gameLoop();
}

// 切换暂停状态
function togglePause() {
    if (isGameOver) return;
    
    isPaused = !isPaused;
    
    if (isPaused) {
        pauseScreen.classList.remove('hidden');
        cancelAnimationFrame(gameLoopId);
    } else {
        pauseScreen.classList.add('hidden');
        gameLoop();
    }
}

// 重新开始游戏
function restartGame() {
    resetBoard();
    currentPiece = getRandomPiece();
    nextPiece = getRandomPiece();
    draw();
    drawNextPiece();
    gameOverScreen.classList.add('hidden');
    isGameOver = false;
    gameLoop();
}

// 切换声音
function toggleSound() {
    soundEnabled = !soundEnabled;
    soundIcon.className = soundEnabled ? 'fa fa-volume-up mr-2' : 'fa fa-volume-off mr-2';
}

// 游戏主循环
function gameLoop(timestamp = 0) {
    if (isPaused || isGameOver) return;
    
    // 计算时间差
    const deltaTime = timestamp - lastTime;
    lastTime = timestamp;
    
    // 下落计数器
    dropCounter += deltaTime;
    if (dropCounter > dropInterval) {
        // 自动下落
        if (!movePiece(0, 1)) {
            lockPiece();
            if (soundEnabled) playLockSound();
        }
        dropCounter = 0;
    }
    
    // 绘制游戏
    draw();
    
    // 继续循环
    gameLoopId = requestAnimationFrame(gameLoop);
}

// 游戏结束
function gameOver() {
    // 更新最高分
    if (score > highScore) {
        highScore = score;
        localStorage.setItem('tetrisHighScore', highScore);
    }
    
    // 更新显示
    finalScore.textContent = score;
    gameOverHighScore.textContent = highScore;
    
    // 显示游戏结束界面
    gameOverScreen.classList.remove('hidden');
    
    // 播放游戏结束音效
    if (soundEnabled) playGameOverSound();
}

// 更新显示
function updateDisplays() {
    scoreDisplay.textContent = score;
    linesDisplay.textContent = lines;
    levelDisplay.textContent = level;
}

// 绘制游戏
function draw() {
    // 清空画布
    ctx.fillStyle = '#121212';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    
    // 绘制网格线
    ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
    ctx.lineWidth = 1;
    
    // 绘制游戏板上的方块
    for (let row = 0; row < ROWS; row++) {
        for (let col = 0; col < COLS; col++) {
            if (board[row][col] !== 0) {
                drawBlock(ctx, col * BLOCK_SIZE, row * BLOCK_SIZE, board[row][col]);
            }
        }
    }
    
    // 绘制当前方块
    if (currentPiece) {
        currentPiece.shape.forEach((row, y) => {
            row.forEach((cell, x) => {
                if (cell !== 0) {
                    drawBlock(ctx, (currentPiece.x + x) * BLOCK_SIZE, (currentPiece.y + y) * BLOCK_SIZE, cell);
                }
            });
        });
    }
    
    // 绘制幽灵方块（显示方块最终落点）
    drawGhostPiece();
}

// 绘制幽灵方块
function drawGhostPiece() {
    if (!currentPiece) return;
    
    // 计算幽灵方块位置
    let ghostY = currentPiece.y;
    while (isValidMove(currentPiece.x, ghostY + 1, currentPiece.shape)) {
        ghostY++;
    }
    
    // 绘制幽灵方块
    ctx.globalAlpha = 0.2;
    currentPiece.shape.forEach((row, y) => {
        row.forEach((cell, x) => {
            if (cell !== 0) {
                drawBlock(ctx, (currentPiece.x + x) * BLOCK_SIZE, (ghostY + y) * BLOCK_SIZE, cell);
            }
        });
    });
    ctx.globalAlpha = 1;
}

// 绘制下一个方块
function drawNextPiece() {
    // 清空画布
    nextCtx.fillStyle = '#121212';
    nextCtx.fillRect(0, 0, nextCanvas.width, nextCanvas.height);
    
    // 计算居中位置
    const offsetX = (nextCanvas.width - nextPiece.shape[0].length * BLOCK_SIZE) / 2;
    const offsetY = (nextCanvas.height - nextPiece.shape.length * BLOCK_SIZE) / 2;
    
    // 绘制下一个方块
    nextPiece.shape.forEach((row, y) => {
        row.forEach((cell, x) => {
            if (cell !== 0) {
                drawBlock(nextCtx, offsetX + x * BLOCK_SIZE, offsetY + y * BLOCK_SIZE, cell);
            }
        });
    });
}

// 绘制单个方块
function drawBlock(context, x, y, type) {
    const color = COLORS[type];
    
    // 绘制方块主体
    context.fillStyle = color;
    context.fillRect(x, y, BLOCK_SIZE, BLOCK_SIZE);
    
    // 绘制高光
    context.fillStyle = 'rgba(255, 255, 255, 0.3)';
    context.fillRect(x, y, BLOCK_SIZE, 4);
    context.fillRect(x, y, 4, BLOCK_SIZE);
    
    // 绘制阴影
    context.fillStyle = 'rgba(0, 0, 0, 0.3)';
    context.fillRect(x, y + BLOCK_SIZE - 4, BLOCK_SIZE, 4);
    context.fillRect(x + BLOCK_SIZE - 4, y, 4, BLOCK_SIZE);
    
    // 绘制边框
    context.strokeStyle = 'rgba(0, 0, 0, 0.5)';
    context.lineWidth = 1;
    context.strokeRect(x, y, BLOCK_SIZE, BLOCK_SIZE);
}

// 播放音效
function playLineClearSound(lines) {
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const oscillator = audioCtx.createOscillator();
    const gainNode = audioCtx.createGain();
    
    // 根据消除的行数调整音高
    const frequencies = [0, 330, 440, 550, 660]; // 对应1-4行
    const frequency = frequencies[lines];
    
    oscillator.type = 'sine';
    oscillator.frequency.setValueAtTime(frequency, audioCtx.currentTime);
    
    gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
    gainNode.gain.linearRampToValueAtTime(0.6, audioCtx.currentTime + 0.05);
    gainNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.3);
    
    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    
    oscillator.start();
    oscillator.stop(audioCtx.currentTime + 0.3);
}

function playLockSound() {
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const oscillator = audioCtx.createOscillator();
    const gainNode = audioCtx.createGain();
    
    oscillator.type = 'triangle';
    oscillator.frequency.setValueAtTime(220, audioCtx.currentTime);
    
    gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
    gainNode.gain.linearRampToValueAtTime(0.5, audioCtx.currentTime + 0.05);
    gainNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.2);
    
    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    
    oscillator.start();
    oscillator.stop(audioCtx.currentTime + 0.2);
}

function playGameOverSound() {
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const oscillator = audioCtx.createOscillator();
    const gainNode = audioCtx.createGain();
    
    oscillator.type = 'sawtooth';
    oscillator.frequency.setValueAtTime(220, audioCtx.currentTime);
    oscillator.frequency.exponentialRampToValueAtTime(
        110, audioCtx.currentTime + 0.5
    );
    
    gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
    gainNode.gain.linearRampToValueAtTime(0.7, audioCtx.currentTime + 0.01);
    gainNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.8);
    
    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    
    oscillator.start();
    oscillator.stop(audioCtx.currentTime + 0.8);
}

// 初始化游戏
window.onload = initGame;
    